package by.siarhei.java.tij.polymorphism.exercises.ex14;

import java.util.Date;
import java.util.Random;

import static java.lang.System.out;

/**
 * @author Siarhei Shchahratsou <s.siarhei@gmail.com>
 * @since 23.03.2014
 */
public abstract class Rodent {
    private static final Random RANDOM = new Random(new Date().getTime());

    public abstract int getWeight();
    public boolean isPredator() {
        return false;
    }

    private Brain brain = new Brain(5);
    private final Territory territory;

    protected Rodent(Territory territory) {
        out.println("construction Rodent");
        this.territory = territory;
        territory.addRodent(this);
    }

    @Override
    public String toString() {
        return "Rodent";
    }

    public static void main(String[] args) {
        Rodent[] rodents = new Rodent[5];
        Territory t = new Territory();
        for (int i = 0; i < rodents.length; i++) {
            rodents[i] = makeRand(t);
        }

        for (Rodent rodent : rodents) {
            print(rodent);
        }

        out.println(t);
    }

    private static void print(Rodent rodent) {
        out.println(rodent + "; weight = " + rodent.getWeight() + "; " + (rodent.isPredator()?"predator":"herbivorous"));
    }

    private static Rodent makeRand(Territory territory) {
        switch (RANDOM.nextInt(3)) {
            case 0: return new Mouse(territory);
            case 1: return new Gerbil(territory);
            case 2: return new Hamster(territory);
            default: throw new IllegalStateException("Unknown kind of Rodent");
        }
    }
}

class Mouse extends Rodent {
    private Voice voice = new Voice("piu-piu");

    Mouse(Territory territory) {
        super(territory);
        out.println("construction Mouse");
    }

    @Override
    public int getWeight() {
        return 100;
    }

    @Override
    public String toString() {
        return "Mouse";
    }
}

class Gerbil extends Rodent {

    private Voice voice = new Voice("girrr");

    Gerbil(Territory territory) {
        super(territory);
        out.println("construction Gerbil");
    }

    @Override
    public int getWeight() {
        return 80;
    }

    @Override
    public String toString() {
        return "Gerbil";
    }

    @Override
    public boolean isPredator() {
        return true;
    }
}

class Hamster extends Rodent {

    private Voice voice = new Voice("hammrr");

    Hamster(Territory territory) {
        super(territory);
        out.println("construction Hamster");
    }

    @Override
    public int getWeight() {
        return 150;
    }

    @Override
    public String toString() {
        return "Hamster";
    }
}

class Brain {
    private int volume;
    Brain() {
        out.println("construction Brain");
    }

    Brain(int volume) {
        out.println("construction Brain: " + volume);
        this.volume = volume;
    }

    public int getVolume() {
        return volume;
    }

    @Override
    public String toString() {
        return "Brain{" +
                "volume=" + volume +
                '}';
    }
}

class Voice {
    String kind;

    Voice(String kind) {
        this.kind = kind;
        out.println("create Voice: " + kind);
    }

    void call() {
        out.println("Voice.call: " + kind);
    }
}

class Territory {
    private static int counter;
    private static final int id = counter++;
    private int rodentsCount;

    public void addRodent(Rodent rodent) {
        out.println("Adding " + rodent);
        rodentsCount++;
    }

    public void removeRodent(Rodent rodent) {
        if (rodentsCount > 0) {
            out.println("Removing " + rodent);
            --rodentsCount;
        }

        out.println("Can't remove");
    }

    @Override
    public String toString() {
        return "Territory#" + id +
                "; total rodents: " + rodentsCount;
    }
}